﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using HossMvp.Core;
using HossMvp.WinForms;

namespace Sample.Views
{
    internal class MainView : AbstractView, IDisposable
    {
        private readonly EventHandler idleCheck;

        public MainView(AbstractViewManager manager, string name, IContentProvider contents)
            : base(manager, name, contents)
        {
            this.BindCommands();

            // enable/disable commands during AppIdle, ensuring bound controls behave as a group
            this.idleCheck = (s, a) => this.Manager.Presenter.CommandProcessor.Enable();
            Application.Idle += this.idleCheck;
        }

        public void Dispose()
        {
            Application.Idle -= this.idleCheck;
        }

        /// <summary>
        /// Binds the commands to form controls.
        /// </summary>
        protected override void BindCommands()
        {
            // NewFile 
            this.Manager.GetCommand("NewDocument").Bind(new[] {
                this.Contents.Get<IComponent>("newToolStripMenuItem"),
                this.Contents.Get<IComponent>("newToolStripButton")
            });

            // OpenFile
            this.Manager.GetCommand("OpenDocument").Bind(new[]
            {
                this.Contents.Get<IComponent>("openToolStripMenuItem"),
                this.Contents.Get<IComponent>("openToolStripButton")
            });

            // SaveFile
            this.Manager.GetCommand("SaveDocument").Bind(new[]
            {
                this.Contents.Get<IComponent>("saveToolStripMenuItem"),
                this.Contents.Get<IComponent>("saveToolStripButton")
            });

            // Close
            this.Manager.GetCommand("CloseView")
                .Bind(this.Contents.Get<IComponent>("exitToolStripMenuItem"));

            // Preferences
            this.Manager.GetCommand("Preferences").Bind(new[]
            {
                this.Contents.Get<IComponent>("preferencesToolStripMenuItem"),
                this.Contents.Get<IComponent>("preferencesToolStripButton")
            });

            // About
            this.Manager.GetCommand("About").Bind(new[] {
                this.Contents.Get<IComponent>("aboutToolStripMenuItem"),
                this.Contents.Get<IComponent>("helpToolStripButton")
            });
        }

        #region Content Provider -- Actions & Properties

        public class MainViewContentProvider : WinFormsContentProvider
        {
            public MainViewContentProvider(Form form, NameDecorator decorator)
                : base(form, decorator)
            {
                this.RegisterActions();

                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.NewFile), this.NewFile);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.OpenFile), this.OpenFile);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.LoadFile), this.LoadFile);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.SaveFile), this.SaveFile);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.Close), this.Close);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.Exit), this.Exit);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.GetEditorStatus), this.GetEditorStatus);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.AskForSave), this.AskForSave);
                //this.RegisterAction(this.Decorator.NameOf<MainViewContentProvider>(a => a.PostClose), this.PostClose);
            }

            private ActionResult NewFile(ActionContext context)
            {
                var richTextBoxFile = this.Get<RichTextBox>("richTextBoxFile");
                richTextBoxFile.Text = string.Empty;

                // clear document
                context.Presenter.ModelManager.Clear();

                this.Form.Text = @"New File";
                return null;
            }

            private ActionResult OpenFile(ActionContext context)
            {
                using (var openFileDialog = new OpenFileDialog())
                {
                    return openFileDialog.ShowDialog() == DialogResult.OK
                        ? new ActionResult().WithProperty("filename", openFileDialog.FileName)
                        : null;
                }
            }

            private ActionResult LoadFile(ActionContext context)
            {
                var richTextBoxFile = this.Get<RichTextBox>("richTextBoxFile");
                richTextBoxFile.Text = context.Get<string>("contents");
                this.Form.Text = context.Get<string>("filename");
                return null;
            }

            private ActionResult SaveFile(ActionContext context)
            {
                var richTextBoxFile = this.Get<RichTextBox>("richTextBoxFile");
                var result = new ActionResult()
                    .WithProperty("filename", this.Form.Text)
                    .WithProperty("contents", richTextBoxFile.Text);
                return result;
            }

            private ActionResult Close(ActionContext context)
            {
                this.Form.Close();
                return null;
            }

            private ActionResult Exit(ActionContext context)
            {
                //Application.Exit();
                return null;
            }

            private ActionResult GetEditorStatus(ActionContext context)
            {
                var richTextBoxFile = this.Get<RichTextBox>("richTextBoxFile");
                var result = new ActionResult().WithProperty("modified", richTextBoxFile.Modified);
                return result;
            }

            private ActionResult AskForSave(ActionContext context)
            {
                if (this.Form.IsDisposed == false)
                {
                    var answer = MessageBox.Show(this.Form, @"File has changed. Do you want to save it?", @"Confirm",
                        MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);

                    var saveAnswer = SaveResponse.Cancel;
                    if (answer == DialogResult.Yes) { saveAnswer = SaveResponse.Yes; }
                    if (answer == DialogResult.No) { saveAnswer = SaveResponse.No; }
                    return new ActionResult().WithProperty("saveAnswer", saveAnswer);
                }

                return null;
            }

            private ActionResult PostClose(ActionContext context)
            {
                return null;
            }
        }

        #endregion Content Provider -- Actions & Properties
    }
}